package net.yslibrary.licenseadapter.internal;

import  net.yslibrary.licenseadapter.TextUtils;
import net.yslibrary.licenseadapter.LogUtil;
import net.yslibrary.licenseadapter.BaseLibrary;
import net.yslibrary.licenseadapter.License;
import net.yslibrary.licenseadapter.Licenses;
import ohos.app.Context;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public final class GitHubLibrary extends BaseLibrary  {
  private static final String TAG = "GitHubLibrary";
 // private static final String URL_BASE_PUBLIC = "https://github.com/";
  private static final String URL_REPO_SPLIT = "/";
  private final List<String> possibleLicenseUrls;
  private static OnCallBack onListeners;
  private static Context gitcontext;

  public GitHubLibrary(String name,String author,License license,
                         List<String> possibleLicenseUrls) {
    super(name, author, license);
    this.possibleLicenseUrls = possibleLicenseUrls;
  }

  private static String loadContents(String url) throws IOException {
    BufferedReader in = null;
    try {
      String licenses = read(in = new BufferedReader(new InputStreamReader(new URL(url).openStream())));
      return licenses;
      } catch (IOException e) {
        LogUtil.error(TAG,"Failed to load license."+"IOException :"+e);
      throw e;
      } finally {
      if (in != null) {
        in.close();
      }
    }
  }

  @Override
  public boolean isLoaded() {
    boolean ret = false;
    if (null != getLicense().getText()) {
        ret = true;
    }
    return ret;
  }

  @Override
  protected License doLoad() {
    if (possibleLicenseUrls.isEmpty()) return getLicense();
    for (String url : possibleLicenseUrls) {
      try {
        License license = new License.Builder(getLicense()).setText(loadContents(url)).setUrl(url).build();
        onListeners.onResultComplete(license);
        return license;
      } catch (IOException ignored) {
        // Handled below
         ignored.printStackTrace();
      }
    }
    LogUtil.error(TAG, "Developer error: no license file found. "
            + "Searched for the following license files:\n" + possibleLicenseUrls);
    throw new IllegalStateException("Unable to load license");
  }

  public static OnCallBack getOnListeners(){
      return onListeners;
  }

  public static void setCompleteInter(OnCallBack var1) {
    onListeners = var1;
  }
  public static void setGitcontext(Context context){
      gitcontext = context;
  }

  @Override
  public boolean hasContent() {
    return true;
  }

/*
  public String getSourceUrl() {
    return URL_BASE_PUBLIC + getAuthor() + URL_REPO_SPLIT + getName();
  }*/

  public static final class Builder {
    //private static final String URL_BASE_RAW = "https://raw.githubusercontent.com/";
    private static final String gitaddress = "resources/rawfile/rawurl.text";
    private static  String URL_BASE_RAW = "";

    private final String author;
    private final String name;
    private final String licenseName;

    private List<String> possibleLicenseUrls;

    public Builder(String shortLink, String licenseName) {
      author = parseRepoAuthor(shortLink);
      name = parseRepoName(shortLink);
      this.licenseName = licenseName;
    }

    private static String parseRepoAuthor( String fullRepo) {
      checkValidRepoUrl(fullRepo);
      return fullRepo.substring(0, fullRepo.indexOf(URL_REPO_SPLIT));
    }

    private static String parseRepoName(String fullRepo) {
      checkValidRepoUrl(fullRepo);
      return fullRepo.substring(fullRepo.indexOf(URL_REPO_SPLIT) + 1);
    }

    private static void checkValidRepoUrl(String fullRepo) {
      int repoSplitIndex = fullRepo.indexOf(URL_REPO_SPLIT);
      if (repoSplitIndex == -1 || repoSplitIndex != fullRepo.lastIndexOf(URL_REPO_SPLIT)) {
        throw new IllegalArgumentException(
            "The GitHub repository url must be of the form `author/repo`.");
      }
    }

    public Builder setRawLicenseUrl(String url) {
      possibleLicenseUrls =
          TextUtils.isEmpty(url) ? Collections.<String>emptyList() : Collections.singletonList(url);
      return this;
    }

    public Builder setRelativeLicensePath( String path) {
      possibleLicenseUrls = new ArrayList<>();
      URL_BASE_RAW = getUrl(gitaddress, gitcontext);
      String fullBase = URL_BASE_RAW + author + "/" + name + "/";
      //String fullBase ="https://gitee.com/herry096/FragmentRigger/blob/master/LICENSE"
      if (path.contains(Licenses.FILE_AUTO)) {
        List<String> possibleFiles = Arrays.asList(
            Licenses.FILE_NO_EXTENSION, Licenses.FILE_TXT, Licenses.FILE_MD);
        for (String possibleFile : possibleFiles) {
            possibleLicenseUrls.add(fullBase + path.replace(Licenses.FILE_AUTO, possibleFile));
        }
      } else {
        possibleLicenseUrls.add(fullBase + path);
      }

      return this;
    }

    public GitHubLibrary build() {
      return new GitHubLibrary(name, author, new License.Builder(licenseName).build(),
          Collections.unmodifiableList(possibleLicenseUrls));
    }

    private String getUrl(String address,Context context) {
      ohos.global.resource.ResourceManager resManager = context.getResourceManager();
      ohos.global.resource.RawFileEntry rawFileEntry = resManager.getRawFileEntry(address);
      StringBuffer stringBuffer = new StringBuffer();
      try {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(rawFileEntry.openRawFile()));
        String line;
        while ((line = bufferedReader.readLine()) != null) {
          stringBuffer.append(line);
        }
        return stringBuffer.toString();
      } catch (IOException e) {
        e.getMessage();
      }
      return "";
    }
  }
  public interface Listener {
    void onComplete(License license,Exception e);
  }
  private String getUrl(String address, Context context) {
    ohos.global.resource.ResourceManager resManager = context.getResourceManager();
    ohos.global.resource.RawFileEntry rawFileEntry = resManager.getRawFileEntry(address);
    StringBuffer stringBuffer = new StringBuffer();
    try {
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(rawFileEntry.openRawFile()));
      String line;
      while ((line = bufferedReader.readLine()) != null) {
        stringBuffer.append(line);
      }
      return stringBuffer.toString();
    } catch (IOException e) {
      e.getMessage();
    }
    return "";
  }
}
